package com.ryskoo.controller.fdfsfile;

import com.alibaba.fastjson.JSON;
import com.ryskoo.util.FastDFSClient;
import com.ryskoo.framework.core.utils.DateFormatHelper;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.InputStream;
import java.util.*;

/**
 * FastDFS文件上传下载公共控制器
 * 
 * @author qyc
 *
 */
@Controller
@RequestMapping(value = "/fastdfs/file")
public class FastDFSController {

	// FastDFS前缀
	@Value("${fdfs.ip.pre}")
	public String fdfsIpPre;
	/**
	 * 文件上传公共类
	 */
	@Autowired
	private FastDFSClient fastDFSClient;

	@Value("${uploadToServer}")
	public Boolean uploadToServer;

	@Value("${localPath}")
	public String localPath;

	@Value("${imageUrl}")
	public String imageUrl;

	/**
	 * 上传文件 并返回文件上传路径
	 *
	 * @param file
	 *            文件对象
	 * @param request
	 * @param response
	 * @return 返回json串
	 */
	@ResponseBody
	@RequestMapping(value = { "/uploadFile" }, method = { RequestMethod.POST })
	public String uploadFile(@RequestParam("file") MultipartFile file,
								HttpServletRequest request, HttpServletResponse response) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		//上传图片到图片服务器
		if (uploadToServer) {
			resultMap = uploadToServer(file);
		} else {
			resultMap = uploadToLocal(file);
		}
		return JSON.toJSONString(resultMap);
	}

	private Map<String,Object> uploadToLocal(MultipartFile file) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			File targetFile = null;
			//返回存储路径
			String msg="";
			String fileName=file.getOriginalFilename();//获取文件名加后缀
			if(fileName!=null&&fileName!=""){
				//文件存储位置
				String path = localPath;
				//文件后缀
				String fileF = fileName.substring(fileName.lastIndexOf("."), fileName.length());
				//新的文件名
				fileName=new Date().getTime() + "_" + new Random().nextInt(1000) + fileF;

				//先判断文件是否存在

				String fileAdd = DateFormatHelper.getNowTimeStr(DateFormatHelper.FORMAT_DATE_STR2);
				File file1 =new File(path + "/" + fileAdd);
				//如果文件夹不存在则创建
				if(!file1 .exists()  && !file1 .isDirectory()){
					file1 .mkdirs();
				}
				targetFile = new File(file1, fileName);
				try {
					file.transferTo(targetFile);
					//本地地址换成外网路径访问（配置nginx之后，不需要这样设置，直接转发到指定的目录）
					String url = path.substring(path.lastIndexOf("/"),path.length());
					msg = imageUrl + url + "/" + fileAdd + "/" + fileName;
					resultMap.put("returnCode", true);
					resultMap.put("fullPath", msg);
				} catch (Exception e) {
					resultMap.put("returnCode", false);
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			resultMap.put("returnCode", false);
			e.printStackTrace();
		}
		return resultMap;
	}

	public Map<String, Object> uploadToServer(MultipartFile file) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			// 1.上传文件并返回文件路径
			String fullPath = fastDFSClient.uploadFile(file);
			System.out.println("fullPath===========" + fullPath);
			// 2.封装返回信息
			resultMap.put("returnCode", true);
			// fullPath 为类似：group1/M00/00/03/wKgB5FqqWcuAIawwAAA0jcKrRPY315.jpg
			resultMap.put("fullPath", fdfsIpPre+fullPath);
		} catch (Exception e) {
			resultMap.put("returnCode", false);
			e.printStackTrace();
		}
		return resultMap;

	}

	/**
	 * KindEditor专用图片上传方法
     * 由于KindEditor对上传图片返回数据有格式要求，故新增此方法
     * KindEditor 返回数据格式
     * 成功 {"error": 0, "url": "http://www.xxx.com/image.jpg"}
     * 失败 {"error": 1, "message": "错误信息"}
	 *
	 * @param image
	 * @return
	 */
    @ResponseBody
    @RequestMapping(value = { "/uploadImage" }, method = { RequestMethod.POST })
	public Map<String, Object> uploadImage(@RequestParam("image") MultipartFile image) {
		Map<String, Object> resultMap = new HashMap<>();
		try {
			// 1.上传文件并返回文件路径
			String fullPath = fastDFSClient.uploadFile(image);
			// 2.封装返回信息
			resultMap.put("error", 0);
			resultMap.put("url", fdfsIpPre + fullPath);
		} catch (Exception e) {
			resultMap.put("error", 1);
            resultMap.put("message", "上传图片失败");
			e.printStackTrace();
		}
		return resultMap;
	}

	/**
	 * 批量上传文件并返回文件上传路径
	 * 
	 * @param files
	 *            文件对象集合
	 * @param request
	 * @param response
	 * @return 返回json串
	 */
	@ResponseBody
	@RequestMapping(value = { "/batchUploadFile" }, method = { RequestMethod.POST })
	public String batchUploadFile(@RequestParam("files") MultipartFile[] files,
			HttpServletRequest request, HttpServletResponse response) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			// 1.批量上传文件
			List<String> fullPaths = fastDFSClient.batchUploadFile(files);
			// 2.封装返回信息
			resultMap.put("returnCode", true);
			// fullPath集合
			resultMap.put("fullPaths", fullPaths);
			resultMap.put("fdfsIpPre", fdfsIpPre);
		} catch (Exception e) {
			resultMap.put("returnCode", false);
			e.printStackTrace();
		}
		return JSON.toJSONString(resultMap);
	}

	/**
	 * 下载文件
	 * 
	 * @param fullPath
	 *            文件路径
	 * @param request
	 * @param response
	 */
	@ResponseBody
	@RequestMapping(value = { "/downFile" }, method = { RequestMethod.GET })
	public void downFile(@RequestParam("fullPath") String fullPath,
			HttpServletRequest request, HttpServletResponse response) {
		InputStream ins = null;
		try {
			// 展示文件名
			String fileName = request.getParameter("fileName");
			// 1.设置下载参数
			response.setContentType("charset=UTF-8");
			response.setCharacterEncoding("UTF-8");
			request.setCharacterEncoding("UTF-8");
			response.setHeader("Content-disposition", "attachment; fileName="
					+ new String(fileName.getBytes("gb2312"), "ISO8859-1"));
			// 2.获取流文件
			ins = fastDFSClient.downloadFile(fullPath);
			IOUtils.copy(ins, response.getOutputStream());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(ins);
		}
	}

	/**
	 * 删除文件
	 * 
	 * @param fullPath
	 *            文件路径
	 * @param request
	 * @param response
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = { "/deleteFile" }, method = { RequestMethod.POST })
	public String deleteFile(@RequestParam("fullPath") String fullPath,
			HttpServletRequest request, HttpServletResponse response) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			//上传图片到图片服务器
			if (uploadToServer) {
				fastDFSClient.deleteFile(fullPath);
			} else {
				//删除图片
				String path = localPath;
				String url = path.substring(path.lastIndexOf("/"),path.length());
				fullPath = fullPath.substring(fullPath.lastIndexOf(url)).replaceFirst(url, "");
				fullPath = localPath + fullPath;
				File f = new File(fullPath);
				f.delete();
			}
			
			// 2.封装返回信息
			resultMap.put("returnCode", true);
		} catch (Exception e) {
			resultMap.put("returnCode", false);
			e.printStackTrace();
		}
		return JSON.toJSONString(resultMap);
	}

	/**
	 * 根据文件路径转化为流打印在页面上
	 * 
	 * @param fullPath
	 *            文件路径
	 * @param request
	 * @param response
	 */
	@ResponseBody
	@RequestMapping(value = { "/getFile" }, method = { RequestMethod.GET })
	public void getFile(@RequestParam("fullPath") String fullPath,
			HttpServletRequest request, HttpServletResponse response) {
		InputStream ins = null;
		try {
			// 1.获取文件流
			ins = fastDFSClient.downloadFile(fullPath);
			// 2.写出
			response.setContentType("image/jpeg");
			// 通过ioutil 对接输入输出流，实现文件下载
			IOUtils.copy(ins, response.getOutputStream());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 关闭流
			IOUtils.closeQuietly(ins);
		}

	}

	/**
	 * 单文件上传demo
	 * 
	 * @return
	 */
	@RequestMapping("/toDemo")
	public String toDemo() {
		return "fastdfsdemo/fdfsDemo";
	}

	/**
	 * 多文件上传demo
	 * 
	 * @return
	 */
	@RequestMapping("/toDemo2")
	public String toDemo2() {
		return "fastdfsdemo/fdfsDemo2";
	}
}
